{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# FVG定义：牛市或熊市中连续三只上涨的阳线或阴线，牛市中第一支蜡烛的上影线与第三只蜡烛的下影线不重合，熊市中第一支蜡烛的下影线与第三只蜡烛的上影线不重合 使用python yfinance matplot 构建可视化实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# FVG 入场 \n",
    "# 止盈在前面趋势的 FVG\n",
    "# 1H FVG ALERT    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from binance.spot import Spot\n",
    "from datetime import datetime\n",
    "import pytz\n",
    "import mplfinance as mpf\n",
    "import numpy as np\n",
    "\n",
    "# 3. 时间戳转换（含时区处理）\n",
    "def convert_to_beijing_time(ts):\n",
    "    tz = pytz.timezone(\"Asia/Shanghai\")\n",
    "    return datetime.fromtimestamp(ts // 1e3, tz)\n",
    "       \n",
    "\n",
    "# symbol = \"BTCUSDT\"\n",
    "# symbol = \"BNBUSDT\"\n",
    "symbol = \"ETHUSDT\"\n",
    "\n",
    "def get_data(interval, limit):\n",
    "    # 1. 获取K线原始数据\n",
    "    client = Spot(base_url=\"https://data-api.binance.vision\")\n",
    "    # interval 1s, 1m, 5m, 1h, 1d,\n",
    "    # 1125-1216 1732475182000-1734289582000 震荡\n",
    "    # 1106-1125 1730833582000-1732475182000 上涨\n",
    "    # 0124 1737659180000\n",
    "    klines = client.klines(\n",
    "        symbol=symbol,\n",
    "        interval=interval,\n",
    "        limit=limit,\n",
    "        # startTime=\"1730833582000\",\n",
    "        # startTime=\"1737659180000\",\n",
    "        # startTime=\"1730833582000\",\n",
    "        # startTime=\"1732475182000\",\n",
    "        # endTime=\"1734289582000\",\n",
    "    )  # 示例：BTC/USDT 1小时K线\n",
    "\n",
    "    # 2. 转换为结构化数据\n",
    "    df = pd.DataFrame(\n",
    "        klines,\n",
    "        columns=[\n",
    "            \"Open Time\",\n",
    "            \"Open\",\n",
    "            \"High\",\n",
    "            \"Low\",\n",
    "            \"Close\",\n",
    "            \"Volume\",\n",
    "            \"Close Time\",\n",
    "            \"Quote Asset Volume\",\n",
    "            \"Number of Trades\",\n",
    "            \"Taker Buy Base\",\n",
    "            \"Taker Buy Quote\",\n",
    "            \"Ignore\",\n",
    "        ],\n",
    "    )\n",
    "\n",
    "    df[\"Time\"] = df[\"Open Time\"].apply(convert_to_beijing_time)\n",
    "\n",
    "    # # 4. 构建OHLC数据框架\n",
    "    ohlc = df.copy()\n",
    "    ohlc = ohlc.set_index(\"Time\").astype(float)  # 确保数值类型正确\n",
    "\n",
    "    return ohlc\n",
    "\n",
    "\n",
    "# data = get_data(interval=\"1d\", limit=200)\n",
    "# data = get_data(interval=\"4h\", limit=100)\n",
    "# data = get_data(interval=\"1h\", limit=1000)\n",
    "# data = get_data(interval=\"30m\", limit=300)\n",
    "data = get_data(interval=\"15m\", limit=300)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 识别FVG模式\n",
    "def detect_fvg(df):\n",
    "    fvg_bull = []\n",
    "    fvg_bear = []\n",
    "    for i in range(len(df)-2):\n",
    "        # 三根连续K线\n",
    "        c1, c2, c3 = df.iloc[i], df.iloc[i+1], df.iloc[i+2]\n",
    "        # print(c1,c2,c3)\n",
    "        # 牛市FVG条件\n",
    "        bull_cond = (\n",
    "            (c1.Close > c1.Open) & (c2.Close > c2.Open) & (c3.Close > c3.Open) &  # 三连阳\n",
    "            (c1.High < c3.Low)  # 上影线与下影线无重叠\n",
    "        )\n",
    "        # 熊市FVG条件\n",
    "        bear_cond = (\n",
    "            (c1.Close < c1.Open) & (c2.Close < c2.Open) & (c3.Close < c3.Open) &  # 三连阴\n",
    "            (c1.Low > c3.High)  # 下影线与上影线无重叠\n",
    "        )\n",
    "\n",
    "        if (bull_cond):\n",
    "            fvg_bull.append((c1.name, c3.name, c1.High, c3.Low))\n",
    "        elif (bear_cond):\n",
    "            fvg_bear.append((c1.name, c3.name, c3.High, c1.Low))\n",
    "\n",
    "    return fvg_bull, fvg_bear\n",
    "\n",
    "\n",
    "fvg_bull, fvg_bear = detect_fvg(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(fvg_bull, fvg_bear)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# 创建填充区域数据\n",
    "lower_band = pd.Series([np.nan] * len(data), index=data.index)\n",
    "upper_band = pd.Series([np.nan] * len(data), index=data.index)\n",
    "\n",
    "# 标记牛市FVG区域\n",
    "for start, end, _, low in fvg_bull:\n",
    "    lower_band.loc[start:end] = low\n",
    "    upper_band.loc[start:end] = data.loc[start, 'High']\n",
    "\n",
    "# 标记熊市FVG区域\n",
    "for start, end, high, _ in fvg_bear:\n",
    "    lower_band.loc[start:end] = data.loc[start, 'Low']\n",
    "    upper_band.loc[start:end] = high\n",
    "\n",
    "\n",
    "\n",
    "# 绘制图表\n",
    "# 定义红涨绿跌颜色规则\n",
    "market_colors = mpf.make_marketcolors(\n",
    "    up='red',      # 上涨 K 线实体颜色\n",
    "    down='green',  # 下跌 K 线实体颜色\n",
    "    # edge='black',  # K 线边框颜色（与涨跌一致时可设为 'i'）\n",
    "    # wick='black',  # 影线颜色\n",
    "    # volume='in',   # 成交量颜色继承主色（up/down）\n",
    "    inherit=True   # 未指定参数继承默认值\n",
    ")\n",
    "\n",
    "# 创建自定义样式\n",
    "custom_style = mpf.make_mpf_style(\n",
    "    marketcolors=market_colors,\n",
    "    gridcolor='lightgray',   # 网格线颜色\n",
    "    gridstyle='--',          # 网格线样式\n",
    "    facecolor='white'        # 图表背景色\n",
    ")\n",
    "\n",
    "mpf.plot(data,\n",
    "         type='candle',\n",
    "         figratio=(32,9),\n",
    "         figscale=1.5,\n",
    "         addplot=[mpf.make_addplot(\n",
    "             upper_band,\n",
    "             fill_between=dict(y1=lower_band.values,\n",
    "                               y2=upper_band.values, alpha=0.2, color='green')\n",
    "         )],\n",
    "        #  style='yahoo',\n",
    "         style=custom_style,  # 应用自定义样式\n",
    "         volume=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# from binance.cm_futures import CMFutures\n",
    "\n",
    "# cm_futures_client = CMFutures()\n",
    "\n",
    "# # get server time\n",
    "# print(cm_futures_client.time())\n",
    "\n",
    "# cm_futures_client = CMFutures(key='<api_key>', secret='<api_secret>')\n",
    "\n",
    "# # Get account information\n",
    "# print(cm_futures_client.account())\n",
    "\n",
    "# # Post a new order\n",
    "# params = {\n",
    "#     'symbol': 'BTCUSDT',\n",
    "#     'side': 'SELL',\n",
    "#     'type': 'LIMIT',\n",
    "#     'timeInForce': 'GTC',\n",
    "#     'quantity': 0.002,\n",
    "#     'price': 59808\n",
    "# }\n",
    "\n",
    "# response = cm_futures_client.new_order(**params)\n",
    "# print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import os\n",
    "# from binance.client import Client\n",
    "\n",
    "# key = \"FC9r3f44u9UgPqnG5wzmW1FlTdUrzu8Bu1G3R18kyv1HdtNo7FedLgsuS3oo6bLH\"\n",
    "# secret = \"fjRHyLILCVw0uj29mFTribS94xeFw35SJXjYpkoCsEybPSFeOdrqyBgdzKZkGSBc\"\n",
    "\n",
    "# proxies = {}\n",
    "# proxy = os.getenv(\"PROXY\")\n",
    "\n",
    "# # proxy = \"http://51.83.140.52:16301\"\n",
    "# if proxy:\n",
    "#     # tmp: improve this in the future\n",
    "#     proxies = {\"http\": proxy, \"https\": proxy}\n",
    "# else:\n",
    "#     print(\"No proxy set\")\n",
    "\n",
    "# futuresClient = Client(\n",
    "#     key,secret, \n",
    "#     {\"proxies\": proxies}, \n",
    "#     # testnet=testnet\n",
    "# )\n",
    "\n",
    "# klines = futuresClient.futures_continous_klines(\n",
    "#     pair=\"BTCUSDT\", contractType=\"PERPETUAL\", interval=\"1h\", limit=100\n",
    "# )\n",
    "# klines"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
